import Sprite2DApplication from "../../src/spriteSystem/Sprite2DApplication";
import IShape from "../../src/interfaces/IShape";
import SpriteFactory from "../../src/factorys/SpriteFactory";
import ISprite from "../../src/interfaces/ISprite";
import CanvasMouseEvent from "../../src/events/CanvasMouseEvent";
import EInputEventType from "../../src/enums/EInputEventType";
import Math2D from "../../src/maths/Math2D";
import ERenderType from "../../src/enums/ERenderType";
import Vector2 from "../../src/maths/Vector2";
import Scale9Data from "../../src/core/Scale9Data";
import Inset from "../../src/maths/Inset";
import EOrder from "../../src/enums/EOrder";
import Canvas2DUtil from "../../src/utils/Canvas2DUtil";
import imgSrc from "./data/scale9.png";

export default class IShape_Event_Hittest_Draw_Test_Demo {

    // 引用一个Sprite2DApplication对象
    private _app: Sprite2DApplication;
    // 用于九宫缩放的图像对象
    private _image: HTMLImageElement;
    // 将添加的IShape存储在该数组中
    private _shapes: IShape[] = [];
    // 用来追踪添加的IShape的索引号
    private _idx: number;
    // 下面的变量用来记录选中精灵原本的颜色
    // 需求是当选中某个精灵后，该精灵变成红色
    // 当鼠标被释放后，要恢复该精灵原本的颜色
    private _lastColor: string | CanvasGradient | CanvasPattern;                                                                         // 追踪上一次的颜色
    public constructor(app: Sprite2DApplication) {
        console.log('IShape_Event_Hittest_Draw_Test_Demo');
        this._lastColor = 'red';
        this._app = app;
        this._idx = 0;  // 这个变量表示当前的坦克精灵位于哪条曲线段上面， 初始化时，将坦克精灵设置在第一条曲线段上
        // 创建HTMLImageElement对象
        this._image = document.createElement('img') as HTMLImageElement;
        // 设置要载入的图片URL路径
        // this._image.src = "./data/scale9.png";
        this._image.src = imgSrc;
        // 使用箭头函数后，this指向当前类
        this._image.onload = (ev: Event): void => {
            // 创建享元类IShape接口
            this._createShapes();
            // 创建grid及初始化
            this.createSprites();
            // 启动Apllication的动画循环
            this._app.start();
        }
    }

    private createSprites(): void {
        // 创建与画布相同尺寸的背景grid形体和精灵
        let grid: IShape = SpriteFactory.createGrid(this._app.canvas.width, this._app.canvas.height);
        let gridSprite: ISprite = SpriteFactory.createSprite(grid, 'grid');
        // 白色填充，黑色网格线
        gridSprite.fillStyle = "white";
        gridSprite.strokeStyle = 'black';
        // 将精灵添加到ISpriteContainer中
        this._app.rootContainer.addSprite(gridSprite);
        // 设置精灵的鼠标事件处理函数
        gridSprite.mouseEvent = (s: ISprite, evt: CanvasMouseEvent): void => {
            // 如果_shapes数组为空，说明还没创建好形体
            if (this._shapes.length === 0) {
                return;
            }
            // gridSprite仅对鼠标右键单击做出响应，不响应鼠标中键和左键
            if (evt.button === 2) {
                // gridSprite仅仅响应鼠标右键的MouseUp事件
                if (evt.type === EInputEventType.MOUSEUP) {
                    // 使用%取模操作，获得周期性索引 [ 0 , 1 , 2 … , 0 , 1 , 2 , … ]
                    this._idx = this._idx % this._shapes.length;
                    // 获得索引指向的享元IShape对象
                    // 然后生成使用该IShape的精灵
                    let sprite: ISprite = SpriteFactory.createSprite(this._shapes[this._idx]);
                    // 让精灵位于鼠标单击处的位置
                    sprite.x = evt.canvasPosition.x;
                    sprite.y = evt.canvasPosition.y;
                    // 对于非Scale9Grid类型的IShape对象，则随机获得-180°~180° 之间的方位
                    // 对于Scale9Grid类来说，旋转后会在9个区域内的各自拼接处形成一条 可见的线段，目前暂时没有解决方案，因此直接不让Scale9Grid进行旋转操作
                    if (sprite.shape.type !== "Scale9Grid") {
                        sprite.rotation = Math2D.random(-180, 180);
                    }
                    sprite.renderType = ERenderType.FILL;
                    if (this._shapes[this._idx].type === 'Line') {
                        sprite.renderType = ERenderType.STROKE;
                        sprite.scaleX = Math2D.random(1, 2);
                        sprite.strokeStyle = Canvas2DUtil.Colors[Math.floor(Math2D.random(3, Canvas2DUtil.Colors.length - 1))];
                    } else {
                        sprite.fillStyle = Canvas2DUtil.Colors[Math.floor(Math2D.random(3, Canvas2DUtil.Colors.length - 1))];
                        if (this._shapes[this._idx].type === 'Circle') {
                            let scale: number = Math2D.random(1, 3);
                            sprite.scaleX = scale;
                            sprite.scaleY = scale;
                        } else if (this._shapes[this._idx].type !== 'Scale9Grid') {
                            sprite.scaleX = Math2D.random(1, 1.5);
                            sprite.scaleY = Math2D.random(1, 1.5);
                        }
                    }
                    sprite.mouseEvent = this.mouseEventHandler.bind(this);
                    sprite.updateEvent = this.updateEventHandler.bind(this);
                    this._app.rootContainer.addSprite(sprite);
                    this._idx++;
                }
            }
        }
    }

    private _createShapes(): void {
        // 清空容器
        this._shapes = [];
        // 创建一条原点在起点的线段
        this._shapes.push(SpriteFactory.createLine(Vector2.create(0, 0), Vector2.create(100, 0)));
        // 创建一条原点在中心的线段
        this._shapes.push(SpriteFactory.createXLine(100, 0.5));
        // 创建原点在不同位置的Rect
        this._shapes.push(SpriteFactory.createRect(10, 10));
        this._shapes.push(SpriteFactory.createRect(10, 10, 0.5, 0.5));
        this._shapes.push(SpriteFactory.createRect(10, 10, 0.5, 0));
        this._shapes.push(SpriteFactory.createRect(10, 10, 0, 0.5));
        this._shapes.push(SpriteFactory.createRect(10, 10, - 0.5, 0.5));
        // 创建圆与椭圆
        this._shapes.push(SpriteFactory.createCircle(10));
        this._shapes.push(SpriteFactory.createEllipse(10, 15));

        // 创建三角形来测试
        let triPoints: Vector2[] = [Vector2.create(0, 0), Vector2.create(20, 0), Vector2.create(20, 20)];
        this._shapes.push(SpriteFactory.createPolygon(triPoints));
        // 创建六边形来测试
        let polyPoints: Vector2[] = [Vector2.create(20, 0),
        Vector2.create(10, 20),
        Vector2.create(- 10, 20),
        Vector2.create(- 20, 0),
        Vector2.create(- 10, - 20),
        Vector2.create(10, - 20)
        ];
        this._shapes.push(SpriteFactory.createPolygon(polyPoints));
        // 创建九宫缩放IShape
        let data: Scale9Data = new Scale9Data(this._image, new Inset(30, 30, 30, 30));
        this._shapes.push(SpriteFactory.createScale9Grid(data, 300, 100, 0.5, 0.5));
        /*
       let points2 : Vector2 [ ] = [
        Vector2 . create ( - 100 , - 100 ) ,
        Vector2 . create ( 0 , - 100.00 ) ,
        Vector2 . create ( 100 , - 100 ) ,
        Vector2 . create ( 0 , 100 ) ,
       ] ;

       this . _shapes . push ( SpriteFactory . createPolygon ( points2 ) ) ;
       */
    }
    private mouseEventHandler(s: ISprite, evt: CanvasMouseEvent): void {
        if (evt.button === 0) {
            if (evt.type === EInputEventType.MOUSEDOWN) {
                if (s.shape.type === "Line") {
                    this._lastColor = s.strokeStyle;
                    s.strokeStyle = 'red';
                    s.lineWidth = 10;
                } else {
                    this._lastColor = s.fillStyle;
                    s.fillStyle = 'red';
                }
            }
            else if (evt.type === EInputEventType.MOUSEUP) {
                if (s.shape.type === "Line") {
                    s.lineWidth = 1;
                    s.strokeStyle = this._lastColor;
                } else {
                    s.fillStyle = this._lastColor;
                }
            }
            else if (evt.type === EInputEventType.MOUSEDRAG) {
                s.x = evt.canvasPosition.x;
                s.y = evt.canvasPosition.y;
            }
        }
    }

    private updateEventHandler(s: ISprite, mesc: number, diffSec: number, order: EOrder): void {
        if (order === EOrder.POSTORDER) {
            return;
        }

        if (s.shape.type !== 'Circle' && s.shape.type !== 'Line' && s.shape.type !== 'Scale9Grid') {
            s.rotation += 100 * diffSec;
            // console.log("up")
        }
    }
}